<template>
  <div class="bus-dispatch-wrapper">
    <div class="container">
      <header class="header">
        <h1 class="main-title">
          城市公交调度系统
        </h1>
        <p class="subtitle">实时监控公交线路运行状态，优化公交调度效率，提升乘客出行体验</p>
      </header>

      <div class="main-grid">
        <!-- 控制面板 -->
        <div class="control-panel">
          <h2 class="panel-title">
            <i class="el-icon-setting"></i>控制面板
          </h2>

          <div class="control-section">
            <div class="form-item">
              <label class="form-label">线路选择</label>
              <el-select v-model="selectedLine" @change="onLineChange" style="width: 100%" :loading="routesLoading">
                <el-option label="全部线路" value="all"></el-option>
                <el-option
                  v-for="route in dispatchRoutes"
                  :key="route.id"
                  :label="`${route.routeName} (${route.routeNumber})`"
                  :value="'route' + route.id"
                ></el-option>
              </el-select>
            </div>

            <div class="form-item">
              <label class="form-label">速度控制</label>
              <el-slider
                v-model="animationSpeed"
                :min="0.5"
                :max="3"
                :step="0.5"
                @input="onSpeedChange"
                style="width: 100%; margin: 12px 0;"
              ></el-slider>
              <div class="speed-labels">
                <span>慢</span>
                <span>快</span>
              </div>
            </div>

            <div class="button-group">
              <el-button type="primary" @click="playAnimation" icon="el-icon-video-play" size="small">
                播放
              </el-button>
              <el-button @click="pauseAnimation" icon="el-icon-video-pause" size="small">
                暂停
              </el-button>
            </div>

            <div class="status-section">
              <h3 class="status-title">线路状态</h3>
              <div class="status-list" v-loading="statusLoading">
                <div class="status-item" v-for="route in routeStatusList" :key="route.id">
                  <span class="status-dot" :style="{backgroundColor: route.color}"></span>
                  <span>{{ route.routeName }}: {{ getStatusText(route.operatingStatus) }}</span>
                  <span class="status-info">{{ route.activeVehicles }}辆车运行</span>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 路线图显示区域 -->
        <div class="map-panel">
          <div class="map-header">
            <h2 class="map-title">
              <i class="el-icon-location"></i>公交路线图
            </h2>
            <div class="time-display">
              <span>当前时间: {{ currentTime }}</span>
            </div>
          </div>

          <div class="map-container">
            <!-- SVG 路线图 -->
            <svg ref="mapSVG" class="map-svg" viewBox="0 0 1000 600" preserveAspectRatio="xMidYMid meet">
              <!-- 背景网格 -->
              <defs>
                <pattern id="grid" width="50" height="50" patternUnits="userSpaceOnUse">
                  <path d="M 50 0 L 0 0 0 50" fill="none" stroke="#f0f0f0" stroke-width="0.5"/>
                </pattern>
              </defs>
              <rect width="100%" height="100%" fill="url(#grid)" />

              <!-- 城市区域背景 -->
              <rect x="100" y="100" width="800" height="400" rx="5" fill="#f9f9f9" stroke="#e0e0e0" stroke-width="1" />

              <!-- 动态路线 -->
              <path
                v-for="route in visibleRoutes"
                :key="'route-' + route.id"
                :ref="'line' + route.id"
                :d="route.pathData"
                fill="none"
                :stroke="route.color"
                stroke-width="6"
                stroke-linecap="round"
                :style="{ opacity: route.visible ? 0.7 : 0 }"
              />

              <!-- 所有站点 -->
              <g v-for="station in visibleStations" :key="'station-' + station.id" class="station" :style="{ opacity: 1 }">
                <circle
                  :cx="station.mapX"
                  :cy="station.mapY"
                  r="8"
                  fill="white"
                  :stroke="station.color || getStationColor(station)"
                  stroke-width="2"
                  :class="'station-' + station.status"
                />
                <text
                  :x="station.mapX"
                  :y="station.mapY - 15"
                  text-anchor="middle"
                  font-size="10"
                  :fill="station.color || getStationColor(station)"
                >
                  {{ station.stationName }}
                </text>
                <!-- 乘客等待指示器 -->
                <circle
                  v-if="station.estimatedPassengers > 15"
                  :cx="station.mapX + 10"
                  :cy="station.mapY - 10"
                  r="3"
                  fill="#ff4444"
                  class="waiting-indicator"
                />
                <!-- 等待车辆数量显示 -->
                <text
                  v-if="station.waitingVehicles > 0"
                  :x="station.mapX - 10"
                  :y="station.mapY - 10"
                  text-anchor="middle"
                  font-size="8"
                  fill="#666"
                >
                  {{ station.waitingVehicles }}车
                </text>
              </g>

              <!-- 换乘站/枢纽站特殊标记 -->
              <g v-for="hubStation in hubStations" :key="'hub-' + hubStation.id">
                <circle
                  :cx="hubStation.mapX"
                  :cy="hubStation.mapY"
                  r="12"
                  fill="none"
                  stroke="#7c3aed"
                  stroke-width="2"
                  stroke-dasharray="4,2"
                />
              </g>

              <!-- 单辆公交车显示 -->
              <g
                v-if="activeBusRoute"
                :ref="'bus' + activeBusRoute.id"
                class="bus"
                :style="{ opacity: 1 }"
              >
                <rect x="-15" y="-10" width="30" height="20" rx="3" :fill="activeBusRoute.color" />
                <circle cx="-10" cy="10" r="4" fill="black" />
                <circle cx="10" cy="10" r="4" fill="black" />
                <text x="0" y="5" text-anchor="middle" fill="white" font-size="10" font-weight="bold">{{ activeBusRoute.routeNumber }}</text>
              </g>
            </svg>

            <!-- 图例 -->
            <div class="legend">
              <div class="legend-title">图例</div>
              <div class="legend-items">
                <div class="legend-item" v-for="route in dispatchRoutes" :key="'legend-' + route.id">
                  <span class="legend-color" :style="{backgroundColor: route.color}"></span>
                  <span>{{ route.routeName }} ({{ route.routeNumber }})</span>
                </div>
                <div class="legend-item">
                  <span class="legend-color station-normal"></span>
                  <span>正常站点</span>
                </div>
                <div class="legend-item">
                  <span class="legend-color station-waiting"></span>
                  <span>有乘客等待</span>
                </div>
                <div class="legend-item">
                  <span class="legend-color transfer"></span>
                  <span>换乘站</span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <footer class="footer">
        <p>© 2023 城市公交调度系统 | 实时监控与调度平台</p>
      </footer>
    </div>
  </div>
</template>

<script>
import { gsap } from 'gsap'
import { MotionPathPlugin } from 'gsap/MotionPathPlugin'
import { getDispatchRoutes, getRouteStatus } from '@/api/bus/routes'
import { getDispatchVehicles, getVehicleRealTimeLocation } from '@/api/bus/vehicles'
import { getDispatchStations, getStationStatus } from '@/api/bus/stations'

// 注册GSAP插件
gsap.registerPlugin(MotionPathPlugin)

export default {
  name: 'BusDispatchMap',
  data() {
    return {
      selectedLine: 'all',
      animationSpeed: 1,
      currentTime: '',
      dispatchRoutes: [],
      routeStatusList: [],
      dispatchVehicles: [],
      dispatchStations: [],
      routesLoading: false,
      statusLoading: false,
      stationsLoading: false,
      timelines: {},
      timeInterval: null,
      statusInterval: null,
      stationsInterval: null
    }
  },

  computed: {
    visibleRoutes() {
      if (this.selectedLine === 'all') {
        return this.dispatchRoutes.map(route => ({
          ...route,
          visible: true
        }))
      } else {
        const selectedRouteId = this.selectedLine.replace('route', '')
        return this.dispatchRoutes.map(route => ({
          ...route,
          visible: route.id.toString() === selectedRouteId
        }))
      }
    },

    visibleStations() {
      if (!this.dispatchStations.length || !this.dispatchRoutes.length) {
        return []
      }

      // 根据线路重新计算站点坐标
      const stationsWithCoords = []
      const stationsPerRoute = Math.floor(this.dispatchStations.length / this.dispatchRoutes.length)

      // 确定要显示的线路
      let routesToShow = this.dispatchRoutes
      if (this.selectedLine !== 'all') {
        const selectedRouteId = this.selectedLine.replace('route', '')
        routesToShow = this.dispatchRoutes.filter(route => route.id.toString() === selectedRouteId)
      }

      routesToShow.forEach((route, routeIndex) => {
        // 找到这条线路在所有线路中的原始索引，用于正确分配站点
        const originalRouteIndex = this.dispatchRoutes.findIndex(r => r.id === route.id)

        // 解析SVG路径获取坐标点
        const pathPoints = this.parseSVGPath(route.pathData)

        // 为当前线路分配站点
        const routeStations = this.dispatchStations.slice(
          originalRouteIndex * stationsPerRoute,
          (originalRouteIndex + 1) * stationsPerRoute
        )

        // 将站点均匀分布在路径上
        routeStations.forEach((station, stationIndex) => {
          const progress = stationIndex / Math.max(1, routeStations.length - 1)
          const coords = this.getCoordinateAtProgress(pathPoints, progress)

          stationsWithCoords.push({
            ...station,
            mapX: coords.x,
            mapY: coords.y,
            routeId: route.id,
            color: route.color
          })
        })
      })

      return stationsWithCoords
    },

    hubStations() {
      // 只显示可见站点中的换乘站
      return this.visibleStations.filter(station => station.isHub === true)
    },

    // 当前活跃的公交车路线（只显示一辆车）
    activeBusRoute() {
      if (this.selectedLine === 'all') {
        // 如果选择全部线路，只显示第一条路线的车
        return this.dispatchRoutes.length > 0 ? this.dispatchRoutes[0] : null
      } else {
        // 如果选择特定线路，显示该线路的车
        const selectedRouteId = this.selectedLine.replace('route', '')
        return this.dispatchRoutes.find(route => route.id.toString() === selectedRouteId) || null
      }
    }
  },

  async mounted() {
    await this.loadRouteData()
    await this.loadRouteStatus()
    await this.loadStationData()
    this.updateTimeDisplay()
    this.timeInterval = setInterval(this.updateTimeDisplay, 60000) // 每分钟更新一次
    this.statusInterval = setInterval(this.loadRouteStatus, 30000) // 每30秒更新状态
    this.stationsInterval = setInterval(this.loadStationData, 60000) // 每分钟更新站点数据

    // 延迟初始化动画，确保DOM渲染完成
    this.$nextTick(() => {
      setTimeout(() => {
        this.initBusAnimations()
      }, 500)
    })
  },

  beforeDestroy() {
    if (this.timeInterval) {
      clearInterval(this.timeInterval)
    }
    if (this.statusInterval) {
      clearInterval(this.statusInterval)
    }
    if (this.stationsInterval) {
      clearInterval(this.stationsInterval)
    }
    // 清理动画
    Object.values(this.timelines).forEach(timeline => {
      if (timeline) timeline.kill()
    })
  },

  methods: {
    // 加载路线数据
    async loadRouteData() {
      try {
        this.routesLoading = true
        const response = await getDispatchRoutes()
        if (response.code === 200) {
          this.dispatchRoutes = response.data || []
          this.$message.success('路线数据加载成功')
        } else {
          this.$message.error('路线数据加载失败: ' + response.msg)
        }
      } catch (error) {
        console.error('加载路线数据失败:', error)
        this.$message.error('路线数据加载失败')
      } finally {
        this.routesLoading = false
      }
    },

    // 加载路线状态
    async loadRouteStatus() {
      try {
        this.statusLoading = true
        const response = await getRouteStatus()
        if (response.code === 200) {
          this.routeStatusList = response.data || []
        } else {
          console.error('路线状态加载失败:', response.msg)
        }
      } catch (error) {
        console.error('加载路线状态失败:', error)
      } finally {
        this.statusLoading = false
      }
    },

    // 加载站点数据
    async loadStationData() {
      try {
        this.stationsLoading = true
        const response = await getDispatchStations()
        if (response.code === 200) {
          this.dispatchStations = response.data || []
        } else {
          console.error('站点数据加载失败:', response.msg)
        }
      } catch (error) {
        console.error('加载站点数据失败:', error)
      } finally {
        this.stationsLoading = false
      }
    },

    // 获取状态文本
    getStatusText(status) {
      const statusMap = {
        'active': '正常运行',
        'delayed': '延误',
        'maintenance': '维护中',
        'inactive': '停运'
      }
      return statusMap[status] || '未知状态'
    },

    // 获取站点颜色
    getStationColor(station) {
      if (station.status === 'maintenance') return '#ff6b6b'
      if (station.status === 'crowded') return '#ffa500'
      if (station.hasWaitingPassengers) return '#4caf50'
      return '#2196f3'
    },

    // 解析SVG路径，提取坐标点
    parseSVGPath(pathData) {
      const points = []
      // 简单解析M L路径命令（假设路径都是M x y L x y L x y ...格式）
      const matches = pathData.match(/(\d+\.?\d*)\s+(\d+\.?\d*)/g)
      if (matches) {
        matches.forEach(match => {
          const [x, y] = match.split(/\s+/).map(Number)
          points.push({ x, y })
        })
      }
      return points
    },

    // 根据进度值获取路径上的坐标
    getCoordinateAtProgress(pathPoints, progress) {
      if (!pathPoints.length) return { x: 0, y: 0 }
      if (pathPoints.length === 1) return pathPoints[0]

      // 限制进度值在0-1之间
      progress = Math.max(0, Math.min(1, progress))

      // 计算在路径上的位置
      const segmentIndex = Math.floor(progress * (pathPoints.length - 1))
      const nextIndex = Math.min(segmentIndex + 1, pathPoints.length - 1)

      if (segmentIndex === nextIndex) {
        return pathPoints[segmentIndex]
      }

      // 线性插值计算坐标
      const segmentProgress = (progress * (pathPoints.length - 1)) - segmentIndex
      const start = pathPoints[segmentIndex]
      const end = pathPoints[nextIndex]

      return {
        x: start.x + (end.x - start.x) * segmentProgress,
        y: start.y + (end.y - start.y) * segmentProgress
      }
    },

    // 初始化公交车动画（只为当前活跃的路线创建动画）
    initBusAnimations() {
      if (!this.activeBusRoute) return

      const route = this.activeBusRoute
      const busRef = this.$refs[`bus${route.id}`]
      const lineRef = this.$refs[`line${route.id}`]

      if (busRef && lineRef && lineRef[0]) {
        // 清理所有旧的动画
        Object.values(this.timelines).forEach(timeline => {
          if (timeline) timeline.kill()
        })
        this.timelines = {}

        // 创建新动画（只为当前活跃路线）
        const duration = (route.estimatedDuration || 15) / this.animationSpeed

        this.timelines[`bus${route.id}`] = gsap.timeline({
          repeat: -1,
          defaults: { duration: duration, ease: "linear" }
        })

        this.timelines[`bus${route.id}`].to(busRef, {
          motionPath: {
            path: lineRef[0],
            align: lineRef[0],
            autoRotate: true,
            alignOrigin: [0.5, 0.5]
          }
        })
        .to(busRef, {
          motionPath: {
            path: lineRef[0],
            align: lineRef[0],
            autoRotate: true,
            alignOrigin: [0.5, 0.5],
            reverse: true
          }
        })
      }
    },

    // 更新时间显示
    updateTimeDisplay() {
      const now = new Date()
      let hours = now.getHours()
      let minutes = now.getMinutes()

      // 格式化时间为 HH:MM
      hours = hours < 10 ? '0' + hours : hours
      minutes = minutes < 10 ? '0' + minutes : minutes

      this.currentTime = `${hours}:${minutes}`
    },

    // 播放动画
    playAnimation() {
      gsap.globalTimeline.play()
      this.$message.success('动画已开始播放')
    },

    // 暂停动画
    pauseAnimation() {
      gsap.globalTimeline.pause()
      this.$message.info('动画已暂停')
    },

    // 速度控制
    onSpeedChange(speed) {
      gsap.globalTimeline.timeScale(speed)
      this.$message.info(`动画速度调整为 ${speed}x`)
    },

    // 线路选择
    onLineChange(selectedLine) {
      let message = ''
      if (selectedLine === 'all') {
        message = '已切换到全部线路（显示第一条线路的公交车）'
      } else {
        const routeId = selectedLine.replace('route', '')
        const route = this.dispatchRoutes.find(r => r.id.toString() === routeId)
        message = `已切换到 ${route ? route.routeName : '未知线路'}`
      }
      this.$message.success(message)

      // 重新初始化动画以适应新的活跃路线
      this.$nextTick(() => {
        setTimeout(() => {
          this.initBusAnimations()
        }, 100)
      })
    }
  }
}
</script>

<style scoped>
.bus-dispatch-wrapper {
  background-color: #f9fafb;
  font-family: system-ui, -apple-system, sans-serif;
  color: #1f2937;
  min-height: 100vh;
  padding: 0;
  margin: 0;
}

.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

.header {
  margin-bottom: 40px;
}

.main-title {
  font-size: 36px;
  font-weight: bold;
  color: #2563eb;
  margin-bottom: 10px;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.05));
}

.subtitle {
  color: #6b7280;
  max-width: 768px;
  font-size: 16px;
  line-height: 1.5;
}

.main-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 24px;
}

@media (min-width: 1024px) {
  .main-grid {
    grid-template-columns: 1fr 3fr;
  }
}

.control-panel {
  background: white;
  border-radius: 12px;
  box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
  padding: 20px;
}

.panel-title {
  font-size: 20px;
  font-weight: 600;
  margin-bottom: 20px;
  display: flex;
  align-items: center;
}

.panel-title i {
  color: #2563eb;
  margin-right: 8px;
}

.control-section {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.form-item {
  display: flex;
  flex-direction: column;
}

.form-label {
  display: block;
  font-size: 14px;
  font-weight: 500;
  color: #374151;
  margin-bottom: 4px;
}

.speed-labels {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: #6b7280;
  margin-top: 4px;
}

.button-group {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

.status-section {
  padding-top: 12px;
  border-top: 1px solid #f3f4f6;
}

.status-title {
  font-weight: 500;
  margin-bottom: 8px;
  font-size: 16px;
}

.status-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.status-item {
  display: flex;
  align-items: center;
  font-size: 14px;
}

.status-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  display: inline-block;
  margin-right: 8px;
}

.status-dot.blue {
  background-color: #2563eb;
}

.status-dot.green {
  background-color: #16a34a;
}

.status-dot.red {
  background-color: #dc2626;
}

.status-info {
  margin-left: auto;
  font-size: 12px;
  color: #6b7280;
}

.map-panel {
  background: white;
  border-radius: 12px;
  box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
  padding: 20px;
}

.map-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.map-title {
  font-size: 20px;
  font-weight: 600;
  display: flex;
  align-items: center;
}

.map-title i {
  color: #f97316;
  margin-right: 8px;
}

.time-display {
  font-size: 14px;
  color: #6b7280;
}

.map-container {
  position: relative;
  background-color: #f9fafb;
  border-radius: 8px;
  overflow: hidden;
  height: 600px;
}

.map-svg {
  width: 100%;
  height: 100%;
}

.legend {
  position: absolute;
  bottom: 16px;
  right: 16px;
  background: rgba(255, 255, 255, 0.9);
  padding: 12px;
  border-radius: 8px;
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
  font-size: 14px;
}

.legend-title {
  font-weight: 500;
  margin-bottom: 8px;
}

.legend-items {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.legend-item {
  display: flex;
  align-items: center;
}

.legend-color {
  width: 16px;
  height: 16px;
  display: inline-block;
  margin-right: 8px;
}

.legend-color.blue {
  background-color: #2563eb;
}

.legend-color.green {
  background-color: #16a34a;
}

.legend-color.red {
  background-color: #dc2626;
}

.legend-color.transfer {
  border: 2px dashed #7c3aed;
}

.legend-color.station-normal {
  background-color: #2196f3;
}

.legend-color.station-waiting {
  background-color: #4caf50;
}

.footer {
  margin-top: 40px;
  text-align: center;
  color: #6b7280;
  font-size: 14px;
}

/* SVG 动画样式 */
.bus {
  cursor: pointer;
  transition: all 0.2s ease;
}

.bus:hover {
  filter: brightness(1.1);
}

.station circle {
  transition: all 0.2s ease;
}

.station:hover circle {
  r: 10;
  stroke-width: 3;
}

/* 站点状态样式 */
.station circle.station-normal {
  fill: white;
  stroke: #2196f3;
}

.station circle.station-waiting {
  fill: white;
  stroke: #4caf50;
}

.station circle.station-maintenance {
  fill: white;
  stroke: #ff6b6b;
}

.station circle.station-crowded {
  fill: white;
  stroke: #ffa500;
}

/* 等待乘客指示器动画 */
.waiting-indicator {
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0% {
    opacity: 1;
    transform: scale(1);
  }
  50% {
    opacity: 0.5;
    transform: scale(1.2);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

/* Element UI 组件样式覆盖 */
.el-select {
  width: 100%;
}

.el-slider {
  margin: 12px 0;
}

/* 响应式适配 */
@media (max-width: 1024px) {
  .main-grid {
    grid-template-columns: 1fr;
  }

  .map-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }

  .legend {
    position: static;
    margin-top: 16px;
  }
}

@media (max-width: 768px) {
  .container {
    padding: 16px;
  }

  .main-title {
    font-size: 28px;
  }

  .control-panel,
  .map-panel {
    padding: 16px;
  }

  .map-container {
    height: 400px;
  }
}
</style>